<script setup lang="ts">
import { CirclePlus, Download, Files, Refresh, RefreshRight, Search, Plus, ArrowRight } from "@element-plus/icons-vue"
import { onMounted, reactive, ref, watch } from "vue"
import jsZip from "jszip"
import {
  GetGraduateInfoResponseData,
  GetStudentByCardIdResponseData,
  IAddStudentRequestData,
  IGetGraduateInfoResponseData,
  IGetStudentByCardIdResponseData,
  IGetStudentResponseData,
  IExportStatisticsExcelRequestData,
  ISearchStudentData
} from "@/api/student/types/student"
import { usePagination } from "@/hooks/usePagination"
import {
  addStudentDataApi,
  deleteStudentDataApi,
  getExcelTemplateApi,
  getGraduateInfoApi,
  getStudentByCardIdApi,
  getStudentDataApi,
  exportStatisticsExcelApi,
  updateStudentDataApi,
  enableAccountApi,
  disableAccountApi
} from "@/api/student"
import { GetGradeIdAndNameList } from "@/api/grade"
import { IAddGradeResponseData, IGetGradeIdAndName } from "@/api/grade/types/grade"
import {
  ElLoading,
  ElMessage,
  ElMessageBox,
  FormInstance,
  FormRules,
  genFileId,
  UploadInstance,
  UploadProps,
  UploadRawFile
} from "element-plus"
import { getImageSize, isImage, openDownload, showPromptMessage } from "@/utils"
import dayjs from "@/utils/day"
import jsPDF from "jspdf"
import FileSaver from "file-saver"
import { IGetProjectIdAndNameResponseData } from "@/api/project/types/project"
import { GetProjectIdAndNameList } from "@/api/project"
import { drawBackground, drawImage, drawText } from "@/utils/canvas"
import { isID } from "@/utils/validate"
import { useUserStore } from "@/store/modules/user"
import { IUserInfoData } from "@/api/login/types/login"
import { getDepartmentIdAndNameList } from "@/api/department"
import { IGetDepartmentData } from "@/api/department/types/department"
import { hasAnthority } from "@/utils"
import { getToken } from "@/utils/cache/cookies"
import { resetStudentPassword } from "@/api/common"
import { sendMsgApi } from "@/api/message/index"

const userInfo = useUserStore().userInfo as IUserInfoData
const auth = useUserStore().auth
const loading = ref(false)
const refreshing = ref(false)
const StudentData = ref<IGetStudentResponseData[]>([])
const ProjectData = ref<IGetProjectIdAndNameResponseData[]>([])
const ExportProjectData = ref<IGetProjectIdAndNameResponseData[]>([])
const { paginationData, handleCurrentChange, handleSizeChange } = usePagination()

onMounted(() => {
  initCanvas()
})

const searchData = reactive<ISearchStudentData>({
  name: "",
  identityCardId: "",
  classId: undefined,
  sex: "",
  enrollmentTime: "",
  graduateTime: "",
  creationTime: "",
  projectId: undefined,
  departmentId: userInfo.departmentId,
  certificateNo: ""
})
const getStudentData = () => {
  if (refreshing.value) return
  refreshing.value = true
  loading.value = true
  getStudentDataApi({ page: paginationData.currentPage, size: paginationData.pageSize, ...searchData })
    .then((res) => {
      paginationData.total = res.data.total
      StudentData.value = res.data.list
    })
    .catch(() => {
      StudentData.value = []
    })
    .finally(() => {
      loading.value = false
      refreshing.value = false
    })
}

const GradeData1 = ref<IAddGradeResponseData[]>([])
const GradeData2 = ref<IAddGradeResponseData[]>([])
const GradeData3 = ref<IAddGradeResponseData[]>([])
const ExportGradeData = ref<IAddGradeResponseData[]>([])
const searchGradeData1 = ref<IGetGradeIdAndName>({
  name: "",
  projectId: undefined,
  departmentId: userInfo.departmentId
})
const searchGradeData2 = ref<IGetGradeIdAndName>({
  name: "",
  projectId: undefined,
  departmentId: userInfo.departmentId
})
const searchGradeData3 = ref<IGetGradeIdAndName>({
  name: "",
  projectId: undefined,
  departmentId: userInfo.departmentId
})
const searchGradeData4 = ref<IGetGradeIdAndName>({
  name: "",
  projectId: undefined,
  departmentId: userInfo.departmentId
})
const getGradeData = (data: IGetGradeIdAndName): Promise<IAddGradeResponseData[]> => {
  return new Promise((resolve) => {
    GetGradeIdAndNameList(data)
      .then((res) => {
        resolve(res.data.list)
      })
      .catch(() => {
        GradeData1.value = []
      })
      .finally(() => {
        loading.value = false
      })
  })
}
const DepartmentData = ref<IGetDepartmentData[]>([])
const ExportDepartmentData = ref<IGetDepartmentData[]>([])
const getDepartmentDataList = async () => {
  loading.value = true
  try {
    const res = await getDepartmentIdAndNameList({ name: "", departmentId: userInfo.departmentId })
    return res.data.list
  } finally {
    loading.value = false
  }
}

onMounted(async () => {
  const res = await getGradeData(searchGradeData1.value)
  const projectData = await getProjectData()
  const departmentData = await getDepartmentDataList()
  if (projectData) {
    ProjectData.value = projectData
    ExportProjectData.value = projectData
  }
  DepartmentData.value = departmentData
  ExportDepartmentData.value = departmentData
  GradeData1.value = res
  GradeData2.value = res
  GradeData3.value = res
})

watch([() => searchGradeData1.value.projectId], async () => {
  GradeData1.value = await getGradeData(searchGradeData1.value)
  searchData.classId = undefined
})

watch([() => searchGradeData2.value.projectId], async () => {
  GradeData2.value = await getGradeData(searchGradeData2.value)
  batchAddData.value.calssId = undefined
})
watch([() => searchGradeData3.value.projectId], async () => {
  GradeData3.value = await getGradeData(searchGradeData3.value)
  batchExportData.value.id = undefined
})
const searchProjectData = ref<{ name: string; departmentId: undefined | number }>({
  name: "",
  departmentId: searchData.departmentId
})
const getProjectData = async () => {
  loading.value = true
  try {
    const res = await GetProjectIdAndNameList(searchProjectData.value)
    return res.data.list
  } catch (error) {
    ProjectData.value = []
  } finally {
    loading.value = false
  }
}

const validateID = (rule: any, value: any, callback: any) => {
  if (value === "") {
    callback(new Error("请输入身份证号"))
  } else if (!isID(value)) {
    callback(new Error("身份证号格式不正确"))
  } else {
    callback()
  }
}

const addDialogVisible = ref(false)
const batchAddDialogVisible = ref(false)
const currentUpdateId = ref<number | undefined>(undefined)
const addFormRules: FormRules = reactive({
  name: [{ required: true, trigger: "blur", message: "请输入学员姓名" }],
  sex: [{ required: true, trigger: "blur", message: "请输入学员性别" }],
  classId: [{ required: true, trigger: "blur", message: "请输入班级" }],
  password: [{ required: true, trigger: "blur", message: "请输入密码" }],
  identityCardId: [
    {
      required: true,
      message: "请输入身份证号",
      trigger: "blur"
    },
    {
      validator: validateID,
      trigger: "blur"
    }
  ],
  enrollmentTime: [{ required: true, trigger: "blur", message: "请输入入学时间" }],
  graduateTime: [{ required: true, trigger: "blur", message: "请输入结业时间" }]
})
const addFormData = reactive<IAddStudentRequestData>({
  name: "",
  identityCardId: "",
  classId: undefined,
  sex: "",
  enrollmentTime: "",
  graduateTime: "",
  identificationPhotoUrl: ""
})
const addFormRef = ref<FormInstance | null>(null)
const sexOptions = [
  {
    label: "女",
    value: "女"
  },
  {
    label: "男",
    value: "男"
  }
]
const uploadAvatarRef = ref<UploadInstance | null>(null)
const handleCreate = () => {
  addFormRef.value?.validate((valid: boolean) => {
    if (valid) {
      if (imageUrl.value !== addFormData.identificationPhotoUrl) {
        uploadAvatarRef.value?.submit()
      } else {
        if (currentUpdateId.value === undefined) {
          addStudentDataApi(addFormData).then(() => {
            ElMessage.success("新增成功")
            addDialogVisible.value = false
            getStudentData()
          })
        } else {
          updateStudentDataApi({
            id: currentUpdateId.value,
            ...addFormData
          }).then(() => {
            ElMessage.success("修改成功")
            addDialogVisible.value = false
            getStudentData()
          })
        }
      }
    } else {
      return false
    }
  })
}
const sendFormRef = ref<FormInstance | null>(null)
const sending = ref(false)
const sendData = ref<any>({})
const sendParams = ref({
  senderId: userInfo.id,
  content: "",
  priority: 0,
  recipientId: ""
})
const options = [
  {
    value: 0,
    label: "一般消息"
  },
  {
    value: 1,
    label: "重要消息"
  }
]
const sendMsg = (row: IGetStudentResponseData) => {
  sending.value = true
  sendData.value = row
}

const confirmSendMsg = () => {
  loading.value = true
  sendParams.value.recipientId = sendData.value.id
  sendMsgApi(sendParams.value)
    .then(() => {
      ElMessage.success("发送成功")
      sending.value = false
    })
    .finally(() => {
      loading.value = false
    })
}

const handleUpdate = (row: IGetStudentResponseData) => {
  currentUpdateId.value = row.id
  addDialogVisible.value = true
  addFormData.classId = row.classId
  addFormData.name = row.name
  addFormData.sex = row.sex
  addFormData.identificationPhotoUrl = row.identificationPhotoUrl
  imageUrl.value = row.identificationPhotoUrl
  addFormData.enrollmentTime = row.enrollmentTime
  addFormData.graduateTime = row.graduateTime
  addFormData.identityCardId = row.identityCardId
}

//#region 删
const handleDelete = (row: IGetStudentResponseData) => {
  ElMessageBox.confirm(`正在删除学员：${row.name}，确认删除？`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    deleteStudentDataApi(row.id).then(() => {
      ElMessage.success("删除成功")
      getStudentData()
    })
  })
}
//#endregion
const gradeDialogVisible = ref(false)
const diplomaData = ref<GetStudentByCardIdResponseData>()
const exportOptionVisible = ref(false)
const exportOptionData = ref({
  hasIdentificationPhotoUrl: "no",
  type: "1"
})

//# canvas
/**
 * 设置证书上的日期
 */
const canvasSetTime = (data: IGetGraduateInfoResponseData) => {
  canvasData.value.enrollmentTime = {
    year: dayjs(data.enrollmentTime).format("YYYY"),
    month: dayjs(data.enrollmentTime).format("MM"),
    day: dayjs(data.enrollmentTime).format("DD")
  }
  canvasData.value.graduateTime = {
    year: dayjs(data.graduateTime).format("YYYY"),
    month: dayjs(data.graduateTime).format("MM"),
    day: dayjs(data.graduateTime).format("DD")
  }
  canvasData.value.generateTime = {
    year: dayjs(data.creationTime).format("YYYY"),
    month: dayjs(data.creationTime).format("MM"),
    day: dayjs(data.creationTime).format("DD")
  }
}
//# end

//# 导出个人证书
const currentExport = ref<IGetStudentResponseData | undefined>(undefined)
const handleGenerate = (row: IGetStudentResponseData) => {
  if (!row.certificateNo) {
    return showPromptMessage("error", "证书未生成,无法导出")
  }
  currentExport.value = row
  exportOptionVisible.value = true
  exportOptionData.value.hasIdentificationPhotoUrl = "no"
}

const handleExport = () => {
  if (!currentExport.value) return
  if (exportOptionData.value.hasIdentificationPhotoUrl === "yes" && !currentExport.value.identificationPhotoUrl) {
    return showPromptMessage("error", "该学员还未上传证件照")
  }
  exportOptionVisible.value = false
  loading.value = true
  getStudentByCardIdApi({ id: currentExport.value.identityCardId, studentId: currentExport.value.id })
    .then(async (res) => {
      diplomaData.value = res
      await individualGenerate(res.data.graduateInfo)
    })
    .catch(() => {
      showPromptMessage("error", "绘制失败")
    })
    .finally(() => {
      loading.value = false
    })
}

const canvasFillCertificate = (
  ctx: CanvasRenderingContext2D,
  canvas: HTMLCanvasElement,
  data: IGetGraduateInfoResponseData | IGetStudentByCardIdResponseData
) => {
  drawText(ctx, canvas, data.name, "middle", 1330, 120, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.year, canvas!.width / 2 - 300, 3194, 55, "#000")
  drawText(ctx, canvas, canvasData.value.generateTime.month, canvas!.width / 2 + 10, 3194, 55, "#000")
  drawText(ctx, canvas, canvasData.value.generateTime.day, canvas!.width / 2 + 260, 3194, 55, "#000")
  drawText(ctx, canvas, data.certificateNo, canvas!.width / 2 - 140, 2375, 65, "#000")
  drawText(ctx, canvas, canvasData.value.enrollmentTime.year, canvas!.width / 2 - 434, 1903, 52, "#000")
  drawText(ctx, canvas, canvasData.value.enrollmentTime.month, canvas!.width / 2 - 244, 1903, 52, "#000")
  drawText(ctx, canvas, canvasData.value.enrollmentTime.day, canvas!.width / 2 - 128, 1903, 52, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.year, canvas!.width / 2 + 70, 1903, 52, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.month, canvas!.width / 2 + 253, 1903, 52, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.day, canvas!.width / 2 + 375, 1903, 52, "#000")
}

const canvasFillTestimonial = (
  ctx: CanvasRenderingContext2D,
  canvas: HTMLCanvasElement,
  data: IGetGraduateInfoResponseData | IGetStudentByCardIdResponseData
) => {
  console.log("绘制证明书")

  drawText(ctx, canvas, data.name, "middle", 1330, 120, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.year, canvas!.width / 2 - 230, 3194, 55, "#000")
  drawText(ctx, canvas, canvasData.value.generateTime.month, canvas!.width / 2 + 100, 3194, 55, "#000")
  drawText(ctx, canvas, canvasData.value.generateTime.day, canvas!.width / 2 + 350, 3194, 55, "#000")
  drawText(ctx, canvas, data.certificateNo, canvas!.width / 2 - 140, 2415, 65, "#000")
  drawText(ctx, canvas, canvasData.value.enrollmentTime.year, canvas!.width / 2 - 424, 1955, 52, "#000")
  drawText(ctx, canvas, canvasData.value.enrollmentTime.month, canvas!.width / 2 - 240, 1955, 52, "#000")
  drawText(ctx, canvas, canvasData.value.enrollmentTime.day, canvas!.width / 2 - 130, 1955, 52, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.year, canvas!.width / 2 + 10, 1955, 52, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.month, canvas!.width / 2 + 203, 1955, 52, "#000")
  drawText(ctx, canvas, canvasData.value.graduateTime.day, canvas!.width / 2 + 315, 1955, 52, "#000")
}

const canvasFillGeneralText = (
  ctx: CanvasRenderingContext2D,
  canvas: HTMLCanvasElement,
  data: IGetGraduateInfoResponseData | IGetStudentByCardIdResponseData
) => {
  if (exportOptionData.value.type === "1") {
    canvasFillCertificate(ctx, canvas, data)
  } else {
    canvasFillTestimonial(ctx, canvas, data)
  }
}

const previewCer = ref("")
const individualAsyncTask = async (info: IGetStudentByCardIdResponseData) => {
  canvasSetTime(info)
  if (canvas && ctx) {
    if (exportOptionData.value.type === "1") {
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      await drawBackground(ctx, canvas, "/images/certificate1.png")
      if (info.identificationPhotoUrl && exportOptionData.value.hasIdentificationPhotoUrl === "yes") {
        await drawImage(ctx, info.identificationPhotoUrl, 1732, 914)
      }

      drawIndividualData(info)
      const pdfString = getPdf(canvas)
      addPdf(pdfString, `${info.name}-${info.projectName}证书1`)

      ctx.clearRect(0, 0, canvas.width, canvas.height)
      await drawBackground(ctx, canvas, "/images/certificate2.png")
      if (info.identificationPhotoUrl && exportOptionData.value.hasIdentificationPhotoUrl === "yes") {
        await drawImage(ctx, info.identificationPhotoUrl, 1732, 914)
      }
      drawIndividualData(info)

      const pdfString2 = getPdf(canvas)
      addPdf(pdfString2, `${info.name}-${info.projectName}证书2`)
    } else {
      await drawBackground(ctx, canvas, "/images/cer.jpg")
      drawIndividualData(info)
      const pdfString = getPdf(canvas)
      previewCer.value = pdfString
      addPdf(pdfString, `${info.name}-${info.projectName}结业证明书`)
    }
    console.log("结束canvas绘制--------")
  }
}

const drawIndividualData = (data: IGetStudentByCardIdResponseData) => {
  if (!ctx || !canvas || !diplomaData.value) return
  canvasFillGeneralText(ctx, canvas, data)
  drawText(ctx, canvas, data.trainingInfo, "middle", 1750, 80, "#000")
  if (exportOptionData.value.type === "1") {
    drawText(ctx, canvas, diplomaData.value.data.headmaster, 580, 2800, 62, "#000")
  }
}

/**
 * 生成结业证书
 * @param graduateInfo
 */
const individualGenerate = async (graduateInfo: IGetStudentByCardIdResponseData[]) => {
  for (let i = 0; i < graduateInfo.length; i++) {
    await individualAsyncTask(graduateInfo[i])
  }
  const zip = new jsZip()
  pdfsData.value.forEach((data) => {
    zip.file(`${data.fileName}.pdf`, data.blob)
  })
  if (exportOptionData.value.type === "1") {
    zip.generateAsync({ type: "blob" }).then((content) => {
      FileSaver.saveAs(
        content,
        graduateInfo[0].name +
          "结业证书-" +
          (exportOptionData.value.hasIdentificationPhotoUrl === "yes" ? "有证件照" : "无证件照") +
          ".zip"
      )
    })
  } else {
    zip.generateAsync({ type: "blob" }).then((content) => {
      FileSaver.saveAs(content, graduateInfo[0].name + "结业证明书.zip")
    })
  }

  pdfsData.value = []
}
//批量导出
const batchExportFormRef = ref<FormInstance | null>(null)
const batchExportData = ref<{ id: number | undefined }>({
  id: undefined
})

const GraduateInfo = ref<GetGraduateInfoResponseData>()
const handleConfirmBatch = () => {
  batchExportFormRef.value?.validate((valid) => {
    if (valid && batchExportData.value.id) {
      getGraduateInfoApi(batchExportData.value.id).then(async (res) => {
        gradeDialogVisible.value = false
        const loading = ElLoading.service({
          text: "导出中...",
          fullscreen: true,
          body: true
        })
        GraduateInfo.value = res
        try {
          await batchGenerate(res.data.graduateInfo)
        } catch (error) {
          showPromptMessage("error", "绘制失败")
        } finally {
          loading.close()
        }
      })
    } else {
      return false
    }
  })
}

const asyncTask = async (info: IGetGraduateInfoResponseData) => {
  canvasSetTime(info)
  if (canvas && ctx) {
    if (exportOptionData.value.type === "1") {
      ctx.clearRect(0, 0, canvas.width, canvas.height)

      await drawBackground(ctx, canvas, "/images/certificate1.png")
      if (info.identificationPhotoUrl && exportOptionData.value.hasIdentificationPhotoUrl === "yes") {
        await drawImage(ctx, info.identificationPhotoUrl, 1732, 914)
      }

      drawData(info)
      const pdfString = getPdf(canvas)
      addPdf(pdfString, info.name + "证书1")

      ctx.clearRect(0, 0, canvas.width, canvas.height)
      await drawBackground(ctx, canvas, "/images/certificate2.png")
      if (info.identificationPhotoUrl && exportOptionData.value.hasIdentificationPhotoUrl === "yes") {
        await drawImage(ctx, info.identificationPhotoUrl, 1732, 914)
      }

      drawData(info)
      const pdfString1 = getPdf(canvas)
      addPdf(pdfString1, info.name + "证书2")
    } else {
      await drawBackground(ctx, canvas, "/images/cer.jpg")
      drawData(info)
      const pdfString = getPdf(canvas)
      previewCer.value = pdfString
      addPdf(pdfString, `${info.name}结业证明书`)
    }
  }
}
const batchGenerate = async (graduateInfo: IGetGraduateInfoResponseData[]) => {
  for (let i = 0; i < graduateInfo.length; i++) {
    await asyncTask(graduateInfo[i])
  }
  const zip = new jsZip()
  pdfsData.value.forEach((data) => {
    zip.file(`${data.fileName}.pdf`, data.blob)
  })

  if (exportOptionData.value.type === "1") {
    zip
      .generateAsync({
        type: "blob"
      })
      .then((content) => {
        FileSaver.saveAs(
          content,
          GraduateInfo.value?.data.className +
            "结业证书-" +
            (exportOptionData.value.hasIdentificationPhotoUrl === "yes" ? "有证件照" : "无证件照") +
            ".zip"
        )
      })
  } else {
    zip
      .generateAsync({
        type: "blob"
      })
      .then((content) => {
        FileSaver.saveAs(content, GraduateInfo.value?.data.className + "结业证明书.zip")
      })
  }
  pdfsData.value = []
}
// 初始化画布
let canvas: null | HTMLCanvasElement = null
const pdfsData = ref<{ blob: Blob; fileName: string }[]>([])
let ctx: CanvasRenderingContext2D | null = null
interface CanvasData {
  generateTime: {
    year: string
    month: string
    day: string
  }
  graduateTime: {
    year: string
    month: string
    day: string
  }
  enrollmentTime: {
    year: string
    month: string
    day: string
  }
}
const canvasData = ref<CanvasData>({
  generateTime: {
    year: "",
    month: "",
    day: ""
  },
  enrollmentTime: {
    year: "",
    month: "",
    day: ""
  },
  graduateTime: {
    year: "",
    month: "",
    day: ""
  }
})
const initCanvas = () => {
  canvas = document.getElementById("myCanvas") as HTMLCanvasElement
  // 创建画布上下文对象
  ctx = canvas.getContext("2d")
}

const drawData = (data: IGetGraduateInfoResponseData) => {
  if (!ctx || !canvas || !GraduateInfo.value) return
  canvasFillGeneralText(ctx, canvas, data)
  drawText(ctx, canvas, GraduateInfo.value.data.trainingInfo, "middle", 1750, 80, "#000")
  if (exportOptionData.value.type === "1") {
    drawText(ctx, canvas, GraduateInfo.value.data.headmaster, 580, 2800, 62, "#000")
  }
}

const getPdf = (canvas: HTMLCanvasElement) => {
  // 将Canvas转换为图片数据
  return canvas.toDataURL("image/jpeg")
}

const addPdf = (dataURL: string, fileName: string) => {
  const pdfDoc = new jsPDF()
  pdfDoc.addImage(dataURL, "JPEG", 0, 0, 210, 297)
  const blob = pdfDoc.output("blob")
  pdfsData.value.push({ blob: blob, fileName })
}

const getExcelTemplate = () => {
  getExcelTemplateApi().then((res) => {
    openDownload(res.blob, res.fileName)
  })
}

const handleSearch = () => {
  if (paginationData.currentPage === 1) {
    getStudentData()
  }
  paginationData.currentPage = 1
}

const resetSearch = () => {
  searchData.name = ""
  searchData.certificateNo = ""
  searchData.classId = undefined
  searchData.creationTime = ""
  searchData.enrollmentTime = ""
  searchData.graduateTime = ""
  searchData.identityCardId = ""
  searchData.departmentId = undefined
  searchData.projectId = undefined
  if (paginationData.currentPage === 1) {
    getStudentData()
  }
  paginationData.currentPage = 1
}

const handleRefresh = () => {
  getStudentData()
}

const resetPassword = (row: IGetStudentResponseData) => {
  ElMessageBox.confirm(`正在重置学员：${row.name}的密码，确认重置？`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(() => {
    loading.value = true
    resetStudentPassword(row.identityCardId)
      .then(() => {
        showPromptMessage("success", "操作成功")
      })
      .finally(() => {
        loading.value = false
      })
  })
}

const imageUrl = ref("")
const handleAvatarSuccess: UploadProps["onSuccess"] = (response) => {
  addFormData.identificationPhotoUrl = response.data.url
  if (currentUpdateId.value === undefined) {
    addStudentDataApi(addFormData).then(() => {
      ElMessage.success("新增成功")
      addDialogVisible.value = false
      getStudentData()
    })
  } else {
    updateStudentDataApi({
      id: currentUpdateId.value,
      ...addFormData
    }).then(() => {
      ElMessage.success("修改成功")
      addDialogVisible.value = false
      getStudentData()
    })
  }
}

const handleAvatarChange: UploadProps["onChange"] = async (uploadFile) => {
  if (isImage(uploadFile.raw?.type)) {
    const imageSize = await getImageSize(uploadFile.raw)
    if (imageSize.width !== 350 || imageSize.height !== 530) {
      showPromptMessage("error", "上传失败：请上传尺寸为350*530px的图片！")
    } else {
      imageUrl.value = URL.createObjectURL(uploadFile.raw!)
    }
  } else {
    showPromptMessage("error", "图片格式错误（请上传jpg、png或jpeg格式的图片）")
  }
}

const validateCreationTime = (rule: any, value: any, callback: any) => {
  if (batchAddData.value.item === 1 && !value) {
    callback(new Error("请选择证书发放时间"))
  } else {
    callback()
  }
}

const validateTrainingInfo = (rule: any, value: any, callback: any) => {
  if (batchAddData.value.item === 1 && !value) {
    callback(new Error("请输入培训信息"))
  } else {
    callback()
  }
}
const batchAddFormRef = ref<FormInstance | null>(null)
const batchAddFormRules: FormRules = reactive({
  calssId: [{ required: true, trigger: "blur", message: "请输入班级" }],
  enrollmentTime: [{ required: true, trigger: "blur", message: "请输入入学时间" }],
  graduateTime: [{ required: true, trigger: "blur", message: "请输入结业时间" }],
  creationTime: [
    {
      validator: validateCreationTime
    }
  ],
  trainingInfo: [
    {
      validator: validateTrainingInfo
    }
  ]
})
const batchAddData = ref<{
  calssId: number | undefined
  enrollmentTime: number | undefined
  graduateTime: number | undefined
  item: number | undefined
  trainingInfo?: string
  creationTime?: number | undefined
}>({
  calssId: undefined,
  enrollmentTime: undefined,
  graduateTime: undefined,
  item: 0,
  trainingInfo: "",
  creationTime: undefined
})

const uploadBatchRef = ref<UploadInstance>()

const batchFileName = ref("")

const handleExceed: UploadProps["onExceed"] = (files) => {
  uploadBatchRef.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  uploadBatchRef.value!.handleStart(file)
}

const handleExceed1: UploadProps["onExceed"] = (files) => {
  uploadAvatarRef.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  uploadAvatarRef.value!.handleStart(file)
}
const resetAddForm = () => {
  searchGradeData2.value.projectId = undefined
  batchAddFormRef.value?.resetFields()
  uploadBatchRef.value?.clearFiles()
  batchFileName.value = ""
}
const handleBatchChange: UploadProps["onChange"] = (uploadFile) => {
  batchFileName.value = uploadFile.name
}
const handleBatchSuccess: UploadProps["onSuccess"] = (response) => {
  if (response.code === 200) {
    showPromptMessage("success", response.msg)
    batchAddDialogVisible.value = false
  } else {
    showPromptMessage("error", response.msg)
  }
}
const handleBatchAdd = () => {
  batchAddFormRef.value?.validate((valid) => {
    if (valid) {
      if (!batchFileName.value) {
        return showPromptMessage("warning", "请选择文件")
      }
      uploadBatchRef.value?.submit()
    } else {
      return false
    }
  })
}

const exportDialogVisible = ref(false)
const exportFormRef = ref<FormInstance | null>(null)
const exportFormData = reactive<IExportStatisticsExcelRequestData>({
  departmentId: userInfo.departmentId === 0 ? undefined : userInfo.departmentId,
  projectId: undefined,
  classId: undefined
})
const handleConfirmExport = () => {
  exportDialogVisible.value = false
  exportFormRef.value?.validate(async (valid) => {
    if (valid) {
      loading.value = true
      const res = await exportStatisticsExcelApi(exportFormData)
      openDownload(res.blob, res.fileName)
      loading.value = false
    } else {
      return false
    }
  })
}

const handleDisableAccount = (row: IGetStudentResponseData) => {
  loading.value = true
  disableAccountApi(row.identityCardId)
    .then(() => {
      getStudentData()
      ElMessage.success("操作成功")
    })
    .finally(() => {
      loading.value = false
    })
}

const handleEnableAccount = (row: IGetStudentResponseData) => {
  loading.value = true
  enableAccountApi(row.identityCardId)
    .then(() => {
      getStudentData()
      ElMessage.success("操作成功")
    })
    .finally(() => {
      loading.value = false
    })
}

const handleCommand = (command: string, row: IGetStudentResponseData) => {
  switch (command) {
    case "reset":
      resetPassword(row)
      break
    case "export":
      handleGenerate(row)
      break
    case "ban":
      ElMessageBox.confirm(`是否确认封禁学员：${row.name}？`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        handleDisableAccount(row)
      })

      break
    case "unseal":
      ElMessageBox.confirm(`是否确认解封学员：${row.name}？`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        handleEnableAccount(row)
      })

      break
  }
}

watch([() => exportFormData.departmentId], async (newV) => {
  if (!newV[0]) {
    exportFormData.projectId = undefined
    exportFormData.classId = undefined
  }
  searchProjectData.value.departmentId = newV[0]
  searchGradeData4.value.departmentId = newV[0]
  const res = await getProjectData()
  if (res) ExportProjectData.value = res
})

watch([() => exportFormData.projectId], async (newV) => {
  searchGradeData4.value.projectId = newV[0]
  const res = await getGradeData(searchGradeData4.value)
  ExportGradeData.value = res
})
const resetForm = () => {
  currentUpdateId.value = undefined
  addFormRef.value?.resetFields()
}
const previewSrcList = ref<string[]>([])
const imageView = ref(false)
watch(
  [
    () => searchData.graduateTime,
    () => searchData.classId,
    () => searchData.creationTime,
    () => searchData.enrollmentTime,
    () => searchData.projectId,
    () => paginationData.currentPage,
    () => paginationData.pageSize
  ],
  getStudentData,
  {
    deep: true,
    immediate: true
  }
)

watch([() => searchData.departmentId], async (newV) => {
  searchProjectData.value.departmentId = newV[0]
  const res = await getProjectData()
  if (res) ProjectData.value = res
  getStudentData()
})
</script>

<template>
  <div class="app-container" v-loading="loading" element-loading-text="加载中">
    <el-card shadow="never" class="search-wrapper">
      <el-form ref="searchFormRef" :inline="true" :model="searchData">
        <el-form-item prop="name" label="学员姓名">
          <el-input v-model="searchData.name" placeholder="请输入" />
        </el-form-item>
        <el-form-item prop="name" label="身份证号">
          <el-input v-model="searchData.identityCardId" placeholder="请输入（身份证号后八位）" />
        </el-form-item>
        <el-form-item prop="name" label="证书编号">
          <el-input v-model="searchData.certificateNo" placeholder="请输入" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
          <el-button :icon="Refresh" @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card shadow="never" class="mt-5">
      <el-form inline>
        <el-form-item label="班级" prop="classId">
          <div class="flex items-center">
            <el-select clearable filterable v-model="searchGradeData1.projectId" placeholder="选择项目(非必选)">
              <el-option v-for="item in ProjectData" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
            <el-icon><ArrowRight /></el-icon>
            <el-select filterable v-model="searchData.classId" placeholder="选择班级(必选)">
              <el-option v-for="item in GradeData1" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </div>
        </el-form-item>
        <el-form-item v-if="auth === '2'" label="办学单位" prop="departmentId">
          <el-select filterable v-model="searchData.departmentId" placeholder="办学单位">
            <el-option v-for="item in DepartmentData" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="项目" prop="projectId">
          <el-select filterable v-model="searchData.projectId" placeholder="选择项目">
            <el-option v-for="item in ProjectData" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="name" label="入学时间">
          <el-date-picker
            value-format="YYYY-MM-DD"
            v-model="searchData.enrollmentTime"
            type="date"
            placeholder="选择入学时间"
          />
        </el-form-item>
        <el-form-item prop="name" label="结业时间">
          <el-date-picker
            value-format="YYYY-MM-DD"
            v-model="searchData.graduateTime"
            type="date"
            placeholder="选择结业时间"
          />
        </el-form-item>
        <el-form-item prop="name" label="发放证书时间">
          <el-date-picker
            value-format="YYYY-MM-DD"
            v-model="searchData.creationTime"
            type="date"
            placeholder="选择发放证书时间"
          />
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="mt-5" shadow="never">
      <div class="flex justify-between">
        <div>
          <el-button
            v-if="hasAnthority('student.add')"
            type="primary"
            :icon="CirclePlus"
            @click="addDialogVisible = true"
            >新增学员</el-button
          >
          <el-button
            v-if="hasAnthority('student.add')"
            type="warning"
            :icon="Files"
            @click="batchAddDialogVisible = true"
            >批量添加</el-button
          >
          <el-button
            v-if="hasAnthority('student.add')"
            type="success"
            color="#3c6382"
            :icon="Download"
            @click="getExcelTemplate"
            >获取批量添加模板</el-button
          >
          <el-button
            v-if="hasAnthority('student.export')"
            type="success"
            :icon="Download"
            @click="gradeDialogVisible = true"
            >导出班级证书</el-button
          >

          <el-button
            v-if="hasAnthority('student.excel')"
            type="success"
            color="#2980b9"
            :icon="Download"
            @click="exportDialogVisible = true"
            >导出结业信息</el-button
          >
        </div>
        <div>
          <el-tooltip content="刷新表格">
            <el-button type="primary" :icon="RefreshRight" circle @click="handleRefresh" />
          </el-tooltip>
        </div>
      </div>
      <div class="mt-2 w-full">
        <el-table :data="StudentData">
          <el-table-column prop="identificationPhotoUrl" label="证件照" min-width="110" align="center">
            <template #default="scope">
              <el-button
                :disabled="!scope.row.identificationPhotoUrl"
                size="small"
                type="primary"
                @click="
                  () => {
                    previewSrcList = [scope.row.identificationPhotoUrl]
                    imageView = true
                  }
                "
                >查看证件照</el-button
              >
            </template>
          </el-table-column>
          <el-table-column prop="name" min-width="120" label="学员姓名" align="center" />
          <el-table-column prop="className" min-width="150" label="班级" show-overflow-tooltip align="center" />
          <el-table-column
            prop="identityCardId"
            label="身份证号"
            show-overflow-tooltip
            min-width="120"
            align="center"
          />
          <el-table-column prop="sex" label="性别" min-width="80" align="center" />
          <el-table-column show-overflow-tooltip prop="projectName" min-width="120" label="项目名称" align="center" />
          <el-table-column
            show-overflow-tooltip
            prop="departmentName"
            min-width="120"
            label="办学单位"
            align="center"
          />
          <el-table-column show-overflow-tooltip prop="enrollmentTime" min-width="120" label="入学时间" align="center">
            <template #default="scope">
              {{ dayjs(scope.row.enrollmentTime).format("YYYY-MM-DD") }}
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip prop="graduateTime" min-width="120" label="结业时间" align="center">
            <template #default="scope">
              {{ dayjs(scope.row.graduateTime).format("YYYY-MM-DD") }}
            </template>
          </el-table-column>
          <el-table-column
            show-overflow-tooltip
            prop="creationTime"
            min-width="120"
            label="发放证书时间"
            align="center"
          >
            <template #default="scope">
              {{ (scope.row.creationTime && dayjs(scope.row.creationTime).format("YYYY-MM-DD")) || "还未生成证书" }}
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip prop="certificateNo" min-width="150" label="证书编号" align="center">
            <template #default="scope">
              {{ scope.row.certificateNo || "暂无证书编号" }}
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" min-width="180" align="center">
            <template #default="scope">
              <el-space>
                <el-button
                  v-if="userInfo.authority === '1' || userInfo.authority === '2'"
                  type="warning"
                  link
                  size="small"
                  @click="sendMsg(scope.row)"
                  >发消息</el-button
                >

                <el-button
                  v-if="hasAnthority('student.update')"
                  type="primary"
                  link
                  size="small"
                  @click="handleUpdate(scope.row)"
                  >修改</el-button
                >
                <el-button
                  v-if="hasAnthority('student.delete')"
                  type="danger"
                  link
                  size="small"
                  @click="handleDelete(scope.row)"
                  >删除</el-button
                >
                <!--      v-if="hasAnthority('admin.grant')" -->

                <el-dropdown trigger="click" @command="(command) => handleCommand(command, scope.row)">
                  <el-link type="info">
                    <el-icon>
                      <MoreFilled />
                    </el-icon>
                  </el-link>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item v-if="hasAnthority('student.export')" command="export"
                        >导出证书</el-dropdown-item
                      >
                      <el-dropdown-item command="reset" v-if="userInfo.authority === '2'">重置密码</el-dropdown-item>
                      <el-dropdown-item v-if="scope.row.able === 1" command="ban">封禁</el-dropdown-item>
                      <el-dropdown-item v-if="scope.row.able === 0" command="unseal">解封</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </el-space>

              <!-- <el-button
                v-if="hasAnthority('student.export')"
                type="success"
                text
                bg
                size="small"
                @click="handleGenerate(scope.row)"
                >导出证书</el-button
              > -->

              <!-- <el-button
                v-if="userInfo.authority === '1' || userInfo.authority === '2'"
                type="info"
                text
                bg
                size="small"
                @click="resetPassword(scope.row)"
                >重置密码</el-button
              > -->
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="mt-2">
        <el-pagination
          background
          :layout="paginationData.layout"
          :page-sizes="paginationData.pageSizes"
          :total="paginationData.total"
          :page-size="paginationData.pageSize"
          :currentPage="paginationData.currentPage"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
    <!-- 新增/修改 -->
    <el-dialog
      v-model="addDialogVisible"
      :title="currentUpdateId === undefined ? '新增学员' : '修改学员'"
      @close="resetForm"
      width="50%"
    >
      <el-form ref="addFormRef" :model="addFormData" :rules="addFormRules" label-width="110px" label-position="left">
        <el-form-item prop="name" label="学员姓名">
          <el-input v-model="addFormData.name" placeholder="请输入" />
        </el-form-item>
        <el-form-item prop="identityCardId" label="身份证号">
          <el-input v-model="addFormData.identityCardId" placeholder="请输入（身份证号后八位）" />
        </el-form-item>
        <el-form-item prop="sex" label="性别">
          <el-select filterable v-model="addFormData.sex" placeholder="选择性别">
            <el-option v-for="item in sexOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item prop="name" label="班级">
          <el-select filterable v-model="addFormData.classId" placeholder="选择班级">
            <el-option v-for="item in GradeData1" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="identificationPhotoUrl" label="证件照">
          <el-upload
            ref="uploadAvatarRef"
            class="avatar-uploader"
            :auto-upload="false"
            :limit="1"
            :on-exceed="handleExceed1"
            action="/api/v2/student_user/uploadIdentificationPhoto"
            :show-file-list="false"
            accept=".jpg,.png,.jpeg"
            :on-change="handleAvatarChange"
            :on-success="handleAvatarSuccess"
            :headers="{ token: getToken() }"
          >
            <img v-if="imageUrl" :src="imageUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item prop="enrollmentTime" label="入学时间">
          <el-date-picker
            value-format="YYYY-MM-DD"
            v-model="addFormData.enrollmentTime"
            type="date"
            placeholder="选择入学时间"
          />
        </el-form-item>
        <el-form-item prop="graduateTime" label="结业时间">
          <el-date-picker
            value-format="YYYY-MM-DD"
            v-model="addFormData.graduateTime"
            type="date"
            placeholder="选择结业时间"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="addDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleCreate">确认</el-button>
      </template>
    </el-dialog>

    <!--    批量添加-->
    <el-dialog v-model="batchAddDialogVisible" @closed="resetAddForm" title="批量新增学员" width="50%">
      <el-form ref="batchAddFormRef" label-width="100" :model="batchAddData" :rules="batchAddFormRules">
        <el-form-item label="班级" prop="calssId">
          <div class="flex items-center">
            <el-select clearable filterable v-model="searchGradeData2.projectId" placeholder="选择项目(非必选)">
              <el-option v-for="item in ProjectData" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
            <el-icon><ArrowRight /></el-icon>
            <el-select filterable v-model="batchAddData.calssId" placeholder="选择班级(必选)">
              <el-option v-for="item in GradeData2" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </div>
        </el-form-item>
        <el-form-item label="学员类型">
          <el-radio-group v-model="batchAddData.item">
            <el-radio :label="0">未结业学员</el-radio>
            <el-radio :label="1">已结业学员</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item prop="trainingInfo" label="培训信息" v-if="batchAddData.item === 1">
          <el-input v-model="batchAddData.trainingInfo" placeholder="请输入" />
        </el-form-item>
        <el-form-item prop="creationTime" label="发放证书时间" v-if="batchAddData.item === 1">
          <el-date-picker
            v-model="batchAddData.creationTime"
            value-format="x"
            type="date"
            placeholder="选择发放证书时间"
          />
        </el-form-item>
        <el-form-item prop="enrollmentTime" label="入学时间">
          <el-date-picker
            v-model="batchAddData.enrollmentTime"
            value-format="x"
            type="date"
            placeholder="选择入学时间"
          />
        </el-form-item>
        <el-form-item prop="graduateTime" label="结业时间">
          <el-date-picker v-model="batchAddData.graduateTime" value-format="x" type="date" placeholder="选择结业时间" />
        </el-form-item>
        <el-form-item label="文件">
          <el-upload
            ref="uploadBatchRef"
            :auto-upload="false"
            :action="
              '/api/v2/student/importStudents?classId=' +
              batchAddData.calssId +
              '&enrollmentTime=' +
              batchAddData.enrollmentTime +
              '&graduateTime=' +
              batchAddData.graduateTime +
              '&item=' +
              batchAddData.item +
              '&trainingInfo=' +
              batchAddData.trainingInfo +
              '&creationTime=' +
              batchAddData.creationTime
            "
            :show-file-list="false"
            :limit="1"
            accept=".xlsx,.xls"
            :on-exceed="handleExceed"
            :on-change="handleBatchChange"
            :on-success="handleBatchSuccess"
            :headers="{ token: getToken() }"
          >
            <el-button type="primary">
              <el-icon> <Plus /> </el-icon>选择文件
            </el-button>
          </el-upload>
          <div v-if="batchFileName" class="px-2 ml-2 rounded bg-gray-100">{{ batchFileName }}</div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="batchAddDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleBatchAdd">确认</el-button>
      </template>
    </el-dialog>

    <!--    选择班级-->
    <el-dialog align-center v-model="gradeDialogVisible" title="班级证书" width="50%">
      <el-form ref="batchExportFormRef" :model="batchExportData" label-width="110">
        <el-form-item prop="id" :rules="{ required: true, message: '请选择班级' }" label="班级">
          <div class="flex items-center">
            <el-select clearable filterable v-model="searchGradeData3.projectId" placeholder="选择项目(非必选)">
              <el-option v-for="item in ProjectData" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
            <el-icon><ArrowRight /></el-icon>
            <el-select filterable v-model="batchExportData.id" placeholder="选择班级(必选)">
              <el-option v-for="item in GradeData3" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </div>
        </el-form-item>
        <el-form-item label="是否包含证件照" v-if="exportOptionData.type === '1'">
          <el-radio-group v-model="exportOptionData.hasIdentificationPhotoUrl">
            <el-radio label="yes">有证件照</el-radio>
            <el-radio label="no">无证件照</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="导出类型">
          <el-radio-group v-model="exportOptionData.type">
            <el-radio label="1">结业证书</el-radio>
            <el-radio label="2">结业证明书</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="gradeDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleConfirmBatch">确认</el-button>
      </template>
    </el-dialog>

    <!--    生成证书画布-->
    <canvas id="myCanvas" />

    <!-- 导出结业信息 -->
    <el-dialog v-model="exportDialogVisible" @closed="resetAddForm" title="导出结业信息" width="50%">
      <el-form ref="exportFormRef" :model="exportFormData" label-width="50">
        <el-form-item
          v-if="auth === '2'"
          prop="departmentId"
          :rules="{ required: true, message: '请选择单位' }"
          label="单位"
        >
          <el-select clearable filterable v-model="exportFormData.departmentId" placeholder="选择单位">
            <el-option v-for="item in ExportDepartmentData" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="projectId" :rules="{ required: true, message: '请选择项目' }" label="项目">
          <el-select
            :disabled="!exportFormData.departmentId"
            clearable
            filterable
            v-model="exportFormData.projectId"
            placeholder="选择项目"
          >
            <el-option v-for="item in ExportProjectData" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item prop="classId" label="班级">
          <el-select
            :disabled="!exportFormData.projectId"
            clearable
            filterable
            v-model="exportFormData.classId"
            placeholder="选择班级"
          >
            <el-option v-for="item in ExportGradeData" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="exportDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleConfirmExport">确认</el-button>
      </template>
    </el-dialog>

    <el-dialog title="导出选项" v-model="exportOptionVisible" width="50%">
      <!-- {{ exportOptionData.hasIdentificationPhotoUrl }} -->
      <el-form :model="exportOptionData" label-width="110">
        <el-form-item label="是否包含证件照" v-if="exportOptionData.type === '1'">
          <el-radio-group v-model="exportOptionData.hasIdentificationPhotoUrl">
            <el-radio label="yes">有证件照</el-radio>
            <el-radio label="no">无证件照</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="导出类型">
          <el-radio-group v-model="exportOptionData.type">
            <el-radio label="1">结业证书</el-radio>
            <el-radio label="2">结业证明书</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="exportOptionVisible = false">取消</el-button>
        <el-button type="primary" @click="handleExport">确认</el-button>
      </template>
    </el-dialog>

    <el-dialog @closed="sendFormRef?.resetFields()" v-model="sending" title="发送消息" width="500">
      <div>
        <el-form ref="sendFormRef" label-width="80" :model="sendParams">
          <el-form-item label="消息类型" prop="priority">
            <el-select v-model="sendParams.priority" placeholder="Select" size="large" style="width: 240px">
              <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="消息内容" prop="content" :rules="[{ required: true }]">
            <el-input
              autosize
              show-word-limit
              maxlength="255"
              v-model="sendParams.content"
              type="textarea"
              placeholder=""
            />
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="sending = false">取消</el-button>
          <el-button :loading="loading" type="primary" @click="confirmSendMsg"> 发送 </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 图片预览 -->
    <el-image-viewer v-if="imageView" :url-list="previewSrcList" @close="imageView = false" />

    <!-- 证书预览 -->
    <!-- <el-image-viewer :url-list="[previewCer]" v-if="previewCer" @close="previewCer = ''" /> -->
  </div>
</template>

<style scoped lang="scss">
canvas {
  width: 0;
  height: 0;
}

:deep(.avatar-uploader .el-upload) {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}
.avatar {
  width: 80px;
}
:deep(.avatar-uploader .el-upload:hover) {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 80px;
  height: 80px;
  text-align: center;
}
:deep(.el-form-item) {
  align-items: center;
}
</style>
